import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;


public class SemeskyUDPClient {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
	     boolean fail=false;
	     int count=1;
	     do
	     {
	        int timeOutPeriod=1; //set time out period. 
	        //TODO: TIMEOUT PERIOD IS USER INPUT
	        DatagramSocket clientSocket = null;
			try {
				clientSocket = new DatagramSocket();
			} catch (SocketException e) {
				e.printStackTrace();
			}
		      InetAddress IPAddress = InetAddress.getByName("localhost");
		      byte[] sendData = new byte[1024];
		      byte[] receiveData = new byte[1024];
		      DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss:SSSS");
		      Date date = new Date();		     
		      String tc1=dateFormat.format(date);//time stamp
		      
		      String s="0";//sequence numbers.
		      String m="One-Line Message M number:" + count++;
		      String buffer = tc1+"#"+s+"#"+m;
		      sendData = buffer.getBytes();
		      DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9999);//buffer, length of buffer, destination ip, port
		      clientSocket.send(sendPacket);
		      


		      DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
	          clientSocket.setSoTimeout(timeOutPeriod); //set timeout period
		      int attempt=0; //amount of resent/receive attempts. 
		      fail=false; //if number of attempts is exceeded. 
		      while(true)
		      {
		         
                  try {
                       //START DEBUG INFO> REMOVE IN FINAL
                       System.out.println("Attempt: "+attempt);
                       attempt++;

                       System.out.println("Read");
                       //END DEBUG 
                       clientSocket.receive(receivePacket);
                       break; //if message is recieved break loop to continue
                  } catch (SocketTimeoutException e) {
                     // resend

                       System.out.println("TIMED OUT");
                       if(attempt>2)//to make sure it attempts a send and receive a full 3 times.
                       {
                            fail=true; //throw failed flag
                            break; //if failed break to continue
                       } 
                       //if haven't failed yet continue. 
                       tc1=dateFormat.format(date);//time stamp
                       
                       s="0";//sequence numbers.
                       buffer = tc1+"#"+s+"#"+m;//resend same message with new  timestamp
                       sendData = buffer.getBytes();
                       sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9999);//buffer, length of buffer, destination ip, port
                       clientSocket.send(sendPacket);
                       //set new timeout period.
                       timeOutPeriod*=2;
                       clientSocket.setSoTimeout(timeOutPeriod);
                  }

		      }
		      if(fail) //if failed
		      {
		           System.out.println("The program attempted to send/receive 3 times and failed....exiting");
		      }
		      else //if not failed print out message from server. 
		      {
		              date = new Date();
		              String tc2 = dateFormat.format(date);
		              String fromServer = new String(receivePacket.getData());
		              //System.out.println("FROM SERVER:" + modifiedSentence);
		              String[] split = fromServer.split("#");
		              //System.out.println(split[0]);
		              //System.out.println(split[1]);
		              //System.out.println(split[2]);
		              
		               String ts = split[0];               
		               tc1 = split[1];           
		               String nextSeq = split[2];
		              
		              System.out.println("tc2(local system time) = "+ tc2);
		              System.out.println("tc1(local system time message sent) = "+ tc1);
		              System.out.println("ts(server time message received = "+ ts);
		              System.out.println("Next sequence number = "+ nextSeq);
		             
		      }
		      clientSocket.close(); //close socket.
	     }while(true&&fail==false); //exited if failed.
		      
	}

}
